package cn.yzj.openapi.aspect;

import cn.yzj.openapi.annotation.OpenApiAuth;
import cn.yzj.openapi.exception.OpenApiException;
import cn.yzj.openapi.utils.JedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

/**
 * open api 权限监听
 *
 * @author gzkemays
 * @since 2022/4/13 11:49
 */
@Component
@Aspect
public class OpenApiAuthAspect {
  @Resource HttpServletRequest request;
  @Resource JedisUtils jedis;
  static final String FORUM_TOKEN = "ForumUser::UserToken::";

  @Before("@annotation(auth)")
  public void doAuthAround(OpenApiAuth auth) {
    String headerKey = auth.header(), customerSecurity = auth.security();
    String token = request.getHeader(headerKey);
    if (token == null) {
      // token 为空
      throw OpenApiException.builder().code(-9999).msg("没有权限").build();
    } else if (StringUtils.isNotBlank(customerSecurity) && !token.equals(customerSecurity)) {
      // token 与自定义的 security 不相同
      throw OpenApiException.builder().code(-9999).msg("权限不足").build();
    } else if (headerKey.equals(HttpHeaders.AUTHORIZATION) && StringUtils.isNotBlank(token)) {
      // 如果 token 是常规 authorization 那么先从论坛中查看 token 是否存在
      Object obj = jedis.get(getForumTokenCacheKey(token));
      if (obj == null) {
        // 检查存在 token 则放行
        throw OpenApiException.builder().code(-9998).msg("token 无效").build();
      }
    }
  }

  String getForumTokenCacheKey(String token) {
    return FORUM_TOKEN + token;
  }
}
